/**
 * knowledge.js
 * 获取布置作业的相关数据
 *
 * created by muming
 * version 1.0.1
 * 2016年04月22日
 */

import * as CONSTANTS from '../../constants/API';
import rp from '../requestProxy';
import DataAccessor, { ENUM_TIME_UNIT, ENUM_DATA_TYPE } from '../dao/DataAccessor';
import { HTTP_RESULT } from '../../constants/protocol';
import { REPLY_DATA } from '../../constants/replyData';
import cloneDeep from 'lodash/cloneDeep';

// 表名
const HOMEWORK = 'homeworkquestion_knowledge';			// 知识点
const TEACHER = 'teacher';								// 教师

// 字段名
const QUESTION = 'question_id';							// 题目
const KNOWLEDGE = 'knowledge_id';						// 知识点
const COMMIT = 'commit_num';							// 提交数
const RIGHT = 'right_num';								// 正确题数

const url = `${CONSTANTS.HOST}${CONSTANTS.DATA_PACKAGE_ON_SERVER}`;

/**
 * 根据提供的表名与字段名创建查询参数
 * @private
 * @param  {String} title     表名
 * @param  {String} field     字段名
 * @param  {String} startDate 开始日期
 * @param  {String} endDate   结束日期
 * @param  {array}  subjects  科目数组
 * @param  {array}  grades    年级数组
 * @return {DataAccessor}     数据访问参数对象
 */
function getObjectsByTitle(title, field, dataType, subjects, grades, startDate, endDate) {
	let dao = new DataAccessor(title, field)
		.dateRange(startDate, endDate)
		.dataType(dataType)
		.timeUnit(ENUM_TIME_UNIT.NONE);

	if (subjects && subjects.length)
		dao.subject(subjects, TEACHER);
	if (grades && grades.length)
		dao.grade(grades, TEACHER);

	return dao;
}

/**
 * 获得拥有基础结构的查询参数, 可以进一步构建查询参数
 * @private
 * @param     {String}                 subjects  学科
 * @param     {String}                 grades    年级
 * @param     {String}                 startDate 开始时间
 * @param     {String}                 endDate   结束时间
 * @return    {Array}                            筛选器查询参数数组
 */
function getObjects (subjects, grades, startDate, endDate) {
	let question = getObjectsByTitle(HOMEWORK, QUESTION, ENUM_DATA_TYPE.COUNT, subjects, grades, startDate, endDate);
	let knowledge = getObjectsByTitle(HOMEWORK, KNOWLEDGE, ENUM_DATA_TYPE.COUNT, subjects, grades, startDate, endDate);
	let commit = getObjectsByTitle(HOMEWORK, COMMIT, ENUM_DATA_TYPE.SUM, subjects, grades, startDate, endDate);
	let right = getObjectsByTitle(HOMEWORK, RIGHT, ENUM_DATA_TYPE.SUM, subjects, grades, startDate, endDate);

	return [question, commit, right];
}

/**
 * 合并数据
 * @Author muming
 * @param  {String} areaName       地域名
 * @param  {String} parentAreaName 父级地域名
 * @param  {String} data           响应数据
 * @return {Array}                 格式化数据
 */
function combineData(areaName, parentAreaName, data) {
	/**
	 * 判断NaN，如果是则返回0
	 */
	function replaceNaN (num) {
		return isNaN(num)? 0: num;
	}

	let [question, commit, right, parentQuestion, parentCommit, parentRight] = data;
	let name = areaName, parentName = parentAreaName;
	let result = [[], [], [areaName, parentAreaName]];

	// 计算题目总数
	let totalCount = 0;
	let parentTotalCount = 0;
	question.forEach((item) => totalCount += Number(item.result));
	parentQuestion.forEach((item) => parentTotalCount += Number(item.result));

	question.forEach((item, index) => {
		result[0][index] = [];
		result[0][index].push(item.show_name);
		result[0][index].push((item.result / totalCount).toFixed(2) * 100);
		result[0][index].push(replaceNaN((right[index].result / commit[index].result).toFixed(2) * 100));
	});
	parentQuestion.forEach((item, index) => {
		result[1][index] = [];
		result[1][index].push(item.show_name);
		result[1][index].push((item.result / parentTotalCount).toFixed(2) * 100);
		result[1][index].push(replaceNaN((parentRight[index].result / parentCommit[index].result).toFixed(2) * 100));
	});

	return result;
}

/**
 * 获取城市视图查询参数
 * @private
 * @param     {String}                 cityId     城市ID
 * @param     {String}                 provinceId 省ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getCityData (cityId, provinceId, subjects, grades, startDate, endDate) {
	let city = getObjects(subjects, grades, startDate, endDate);
	let province = cloneDeep(city);

	city = city.map((item) => item.city(cityId, TEACHER));
	province = province.map((item) => item.province(provinceId, TEACHER));

	return [...city, ...province];
}

/**
 * 获取区县视图查询参数
 * @private
 * @param     {String}                 countyId   城市ID
 * @param     {String}                 cityId 	  省ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getCountyData (countyId, cityId, subjects, grades, startDate, endDate) {
	let county = getObjects(subjects, grades, startDate, endDate);
	let city = cloneDeep(county);

	county = county.map((item) => item.county(countyId, TEACHER));
	city = city.map((item) => item.city(cityId, TEACHER));

	return [...county, ...city];
}

/**
 * 获取学校视图查询参数
 * @private
 * @param     {String}                 schoolId   城市ID
 * @param     {String}                 countyId   省ID
 * @param     {String}                 subjects   学科
 * @param     {String}                 grades     年级
 * @param     {String}                 startDate  开始时间
 * @param     {String}                 endDate    结束时间
 * @return    {Array}                             查询参数数组
 */
function getSchoolData (schoolId, countyId, subjects, grades, startDate, endDate) {
	let school = getObjects(subjects, grades, startDate, endDate);
	let county = cloneDeep(school);

	school = school.map((item) => item.school(schoolId, TEACHER));
	county = county.map((item) => item.county(countyId, TEACHER));

	return [...school, ...county];
}

/**
 * 获取城市视图知识点分布
 * @Author muming
 * @public
 * @param  {String} options.cityId       城市ID
 * @param  {String} options.cityName     城市名
 * @param  {String} options.provinceId   省ID
 * @param  {String} options.provinceName 省名
 * @param  {String} options.subjects     学科
 * @param  {String} options.grades       年级
 * @param  {String} options.startDate    开始时间
 * @param  {String} options.endDate      结束时间
 * @param  {String} options.group	     数据分组
 * @return {Promise}                     响应数据
 */
export function viewCityList ({ cityId, cityName, provinceId, provinceName, subjects, grades, startDate, endDate, group }) {
	let dataObjects = getCityData(cityId, provinceId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item, index) => {
		return item.multiUnit(`${HOMEWORK}-${KNOWLEDGE}`).timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = combineData(cityName, provinceName, result.data);

				if(group === 'chart'){
					data[0] = data[0].sort((a, b) => b[0] - a[0]).slice(0, 30);
					data[1] = data[1].sort((a, b) => b[0] - a[0]).slice(0, 30);
				}

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取区县视图知识点分布
 * @Author muming
 * @public
 * @param  {String} options.countyId     城市ID
 * @param  {String} options.countyName   城市名
 * @param  {String} options.cityId   	 省ID
 * @param  {String} options.cityName 	 省名
 * @param  {String} options.subjects     学科
 * @param  {String} options.grades       年级
 * @param  {String} options.startDate    开始时间
 * @param  {String} options.endDate      结束时间
 * @param  {String} options.group	     数据分组
 * @return {Promise}                     响应数据
 */
export function viewCountyList ({ countyId, countyName, cityId, cityName, subjects, grades, startDate, endDate, group }) {
	let dataObjects = getCountyData(countyId, cityId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item, index) => {
		return item.multiUnit(`${HOMEWORK}-${KNOWLEDGE}`).timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = combineData(countyName, cityName, result.data);

				if(group === 'chart'){
					data[0] = data[0].sort((a, b) => b[0] - a[0]).slice(0, 30);
					data[1] = data[1].sort((a, b) => b[0] - a[0]).slice(0, 30);
				}

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};

/**
 * 获取学校视图知识点分布
 * @Author muming
 * @public
 * @param  {String} options.schoolId     学校ID
 * @param  {String} options.schoolName   学校名
 * @param  {String} options.countyId   	 区县ID
 * @param  {String} options.countyName 	 区县名
 * @param  {String} options.subjects     学科
 * @param  {String} options.grades       年级
 * @param  {String} options.startDate    开始时间
 * @param  {String} options.endDate      结束时间
 * @param  {String} options.group	     数据分组
 * @return {Promise}                     响应数据
 */
export function viewSchoolList ({ schoolId, schoolName, countyId, countyName, subjects, grades, startDate, endDate, group }) {
	let dataObjects = getSchoolData(schoolId, countyId, subjects, grades, startDate, endDate);
	dataObjects = dataObjects.map((item, index) => {
		return item.multiUnit(`${HOMEWORK}-${KNOWLEDGE}`).timeUnit(ENUM_TIME_UNIT.NONE).packageType('').jsonObject();
	});

	return rp.post(url, dataObjects)
		.then((result) => {
			if(result.code === HTTP_RESULT.SUCCESS) {
				let data = combineData(schoolName, countyName, result.data);

				if(group === 'chart'){
					data[0] = data[0].sort((a, b) => b[0] - a[0]).slice(0, 30);
					data[1] = data[1].sort((a, b) => b[0] - a[0]).slice(0, 30);
				}

				return Object.assign({}, REPLY_DATA, {
					code: HTTP_RESULT.SUCCESS,
					data
				});
			}

			return result;
		});
};









